﻿using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Arroguella.Utilities;
using Arroguella.Entities;

namespace Arroguella.Panels
{
    /// <summary>
    /// This panel sits on the main Game Screen and relays critical player information.
    /// </summary>
    public class PlayerInfoPanel : ScreenPanel
    {
        #region Constructor

        public PlayerInfoPanel(Game game)
            : base(game)
        {
        }

        #endregion

        #region Events
        #endregion

        #region Methods

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            SetSizeAndShape(0, 0, 300, 10);

            BackgroundColor = Color.Blue;

            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            Elements.Clear();

            string lvl = string.Format("Character Level: {0}", Player.Level);
            AddElement(lvl, Color.MediumPurple);

            string xp = string.Format("XP: {0} / {1}", Player.XP, Player.XpForNextLevel);
            AddElement(xp, Color.Purple);

            string hp = string.Format("HP: {0} / {1}", Player.CurrentHealth, Player.MaxHealth);
            AddElement(hp, Color.Pink);

            string mana = string.Format("Mana: {0} / {1}", Player.CurrentMana, Player.MaxMana);
            AddElement(mana, Color.DodgerBlue);

            AddElement("--", Color.Gray);

            string defense = string.Format("DEFENSE {0}", Player.Defense);
            AddElement(defense, Color.LightGray);

            // Weapon/Attack stats
            EquipmentEntity primary = Player.PrimaryWeapon;
            EquipmentEntity secondary = Player.SecondaryWeapon;
            string weapon1 = string.Empty, accuracy1 = string.Empty, damage1 = string.Empty;
            string weapon2 = string.Empty, accuracy2 = string.Empty, damage2 = string.Empty;
            if (primary != null)
            {
                weapon1 = string.Format("PRIMARY: {0}", primary.Name);
                accuracy1 = string.Format(" ACC {0}", primary.AccuracyModifier);
                float damageMod1 = primary.DamageModifier + Player.Strength;
                string primaryDamageMod = damageMod1 != 0 ? string.Format(" {0}{1}", damageMod1 > 0 ? "+" : "-", damageMod1) : string.Empty;
                damage1 = string.Format(" DMG {0}-{1}{2}", primary.MinDamage, primary.MaxDamage, primaryDamageMod);
            }

            if (secondary != null)
            {
                weapon2 = string.Format("SECONDARY: {0}", secondary.Name);
                accuracy2 = string.Format(" ACC {0}", secondary.AccuracyModifier);
                float damageMod2 = secondary.DamageModifier + Player.Strength;
                string secondaryDamageMod = damageMod2 != 0 ? string.Format(" {0}{1}", damageMod2 > 0 ? "+" : "-", damageMod2) : string.Empty;
                damage2 = string.Format(" DMG {0}-{1}{2}", secondary.MinDamage, secondary.MaxDamage, secondaryDamageMod);
            }

            if(primary == null && secondary == null)
            {
                weapon1 = "Unarmed";
                accuracy1 = string.Format(" ACC {0}", Player.AccuracyModifierFromEquipment);
                float damageMod = Player.DamageModifierFromEquipment + Player.Strength;
                string primaryDamageMod = damageMod != 0 ? string.Format(" {0}{1}", damageMod > 0 ? "+" : "-", damageMod) : string.Empty;
                damage1 = string.Format(" DMG {0}-{1}{2}", 1, 4, primaryDamageMod);
            }

            AddElement(weapon1, Color.Yellow);
            AddElement(accuracy1, Color.Yellow);
            AddElement(damage1, Color.Yellow);

            if (secondary != null)
            {
                AddElement(weapon2, Color.Yellow);
                AddElement(accuracy2, Color.Yellow);
                AddElement(damage2, Color.Yellow);
            }

            AddElement("--", Color.Gray);

            // Money
            string money;
            float amount = Player.Money;
            if (amount < 0.10)
            {
                money = string.Format("Money: {0}", Player.GetProperty("CP"));
                AddElement(money, Color.DarkOrange);
            }
            else if (amount >= 0.10 && amount < 1.00)
            {
                money = string.Format("Money: {0}", Player.GetProperty("SP"));
                AddElement(money, Color.LightSlateGray);
            }
            else if (amount >= 1.00)
            {
                money = string.Format("Money: {0}", Player.GetProperty("GP"));
                AddElement(money, Color.Goldenrod);
            }
            AddElement("--", Color.Gray);

            AddElement("[I] Inventory", Color.DarkGray);
            AddElement("[C] Character", Color.DarkGray);
            AddElement("[G] Get", Color.DarkGray);
            AddElement("[<] Down", Color.DarkGray);
            AddElement("[>] Up", Color.DarkGray);

            AddElement("--", Color.Gray);
        }

        /// <summary>
        /// Allows the game component to draw itself
        /// </summary>
        public override void Draw(SpriteBatch spriteBatch)
        {
            // Draw the background
            Utils.DrawFilledRectangle(BackgroundColor, SizeAndShape, spriteBatch, Arroguella.GraphicsDevice);

            // Draw the elements
            Rectangle elementRect = new Rectangle(SizeAndShape.X + 3, SizeAndShape.Y, ELEMENT_WIDTH, ELEMENT_HEIGHT);
            foreach (KeyValuePair<string, Color> element in Elements)
            {
                // Special case, convert any instance of multiple dashes to a line
                if (element.Key.Contains("--"))
                {
                    Rectangle line = new Rectangle(elementRect.X, elementRect.Y + (elementRect.Height/2), ELEMENT_WIDTH - 6, 1);
                    Utils.DrawFilledRectangle(element.Value, line, spriteBatch, Arroguella.GraphicsDevice);
                }
                else
                {
                    //Utils.DrawString(spriteBatch, PlayerInfoFont, element.Key, element.Value, elementRect, Utils.Alignment.Left);
                    Utils.DrawStringWrappedInRectangle(element.Key, elementRect, element.Value, PlayerInfoFont, spriteBatch);
                }
                
                elementRect.Y += ELEMENT_HEIGHT + 1;
            }
        }

        #endregion

        #region Elements

        private List<KeyValuePair<string, Color>> Elements = new List<KeyValuePair<string, Color>>();

        private void AddElement(string text, Color color)
        {
            Elements.Add(new KeyValuePair<string, Color>(text, color));
        }

        private const int ELEMENT_HEIGHT = 15;

        private int ELEMENT_WIDTH { get { return SizeAndShape.Width; } }

        private const int ELEMENT_SPACING = 10;

        #endregion

        #region Properties

        /// <summary>
        /// Reference to the player.
        /// </summary>
        internal Player Player { get { return Arroguella.GameScreen.Player; }  }

        #endregion
    }
}
